package obecto.task
{
	import flash.utils.clearTimeout;
	
	import obecto.event.TaskEvent;
	import obecto.event.TaskEventKind;
	import obecto.utility.CloneUtility;
	
	public class MultiTargetTask extends BaseInterruptibleTask
	{
		public var prototypeTask : BaseTask;
		
		public var targets : Array;
		
		public var itemDelayOffset : Number;
		
		protected var tasks : Array;
		
		protected function clonePrototype(target : Object) : BaseTask
		{
			var result : BaseTask = CloneUtility.clone(prototypeTask) as BaseTask;
			return result;
		}
		
		override protected function startActual() : void
		{
			tasks = [];
			
			var target : Object;
			var task : BaseTask;
			
			for (var i : int = 0; i < targets.length; i++)
			{
				target = targets[i];
				task = clonePrototype(target);
				
				if (!isNaN(itemDelayOffset))
				{
					task.delay = i * itemDelayOffset;
				}
				
				if (i == targets.length - 1) // this is the last tween
				{
					task.addEventListener(TaskEvent.COMPLETE, handleLastTaskComplete);
				}
				
				tasks.push(task);
			}
			
			for each (task in tasks)
			{
				task.start();
			}
		}
		
		override public function end() : void
		{
			_reversing = false;
			
			if (running == true)
			{	
				dispatchEvent(new TaskEvent(TaskEvent.INTERRUPT, TaskEventKind.END));
			}
			
			for each (var task : Object in tasks)
			{
				if (task is IInterruptibleTask)
				{
					IInterruptibleTask(task).end();
				}
			}
			
			complete();
		}
		
		override public function interrupt() : void
		{
			if (running)
			{
				_running = false;
				_reversing = false;
				
				if (!isNaN(delayId))
				{
					clearTimeout(delayId);
					delayId = NaN;
				}
				
				for each (var task : Object in tasks)
				{
					if (task is IInterruptibleTask)
					{
						IInterruptibleTask(task).interrupt();
					}
				}
				
				dispatchEvent(new TaskEvent(TaskEvent.INTERRUPT, TaskEventKind.INTERRUPT));
			}
		}
		
		override public function reverse() : void
		{
			if (!reversing)
			{	
				_reversing = true;
				
				if (running)
				{
					for each (var task : Object in tasks)
					{
						if (task is IInterruptibleTask)
						{
							IInterruptibleTask(task).reverse();
						}
					}
					
					dispatchEvent(new TaskEvent(TaskEvent.INTERRUPT, TaskEventKind.REVERSE));
				}
			}
		}
		
		override public function forward() : void
		{
			if (running && reversing)
			{
				_reversing = false;
				
				for each (var task : Object in tasks)
				{
					if (task is IInterruptibleTask)
					{
						IInterruptibleTask(task).forward();
					}
				}
				
				dispatchEvent(new TaskEvent(TaskEvent.START, TaskEventKind.FORWARD));
			}
		}
		
		override public function rollback() : void
		{
			_reversing = true;
			
			if (running)
			{	
				for each (var task : Object in tasks)
				{
					if (task is IInterruptibleTask)
					{
						IInterruptibleTask(task).rollback();
					}
				}
				
				dispatchEvent(new TaskEvent(TaskEvent.INTERRUPT, TaskEventKind.ROLLBACK));
			}
			
			completeReverse();
		}
		
		protected function handleLastTaskComplete(e : TaskEvent) : void 
		{
			complete();
		}
		
	}
}